package com.learn.security.theory.symmetric_encryption;

import com.learn.security.utils.symmetric_encryption.PBEUtil;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.Key;
import java.security.SecureRandom;

/**
 * PBE算法
 */
public class PBETest {

    private static final String encodeStr = "PBE test";
    /**
     * 密码
     */
    private static final String password = "enn";

    public static void main(String[] args) {
        PBEUtil();
        jdkPBE();

    }

    // 用PBEUtil实现：PBE
    private static void PBEUtil() {
        System.out.println("原文: " + encodeStr);

        System.out.println("密码: " + password);
        try {
            // 初始化盐
            byte[] salt = PBEUtil.initSalt();

            // 加密
            byte[] data = PBEUtil.encrypt(encodeStr.getBytes(), password, salt);
            System.err.println("PBEUtil pbe加密后: " + PBEUtil.encryptBASE64(data));

            // 解密
            byte[] output = PBEUtil.decrypt(data, password, salt);

            System.err.println("PBEUtil pbe解密后: " + new String(output));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 用jdk实现:
    private static void jdkPBE() {
        try {
            // 初始化盐
            SecureRandom random = new SecureRandom();
            byte[] salt = random.generateSeed(8);

            // 口令与密钥
            PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");
            Key key = factory.generateSecret(pbeKeySpec);


            // 加密
            PBEParameterSpec pbeParameterSpac = new PBEParameterSpec(salt, 100);
            Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES");
            cipher.init(Cipher.ENCRYPT_MODE, key, pbeParameterSpac);
            byte[] result = cipher.doFinal(encodeStr.getBytes());
            System.out.println("jdk pbe encrypt:" + Base64.encodeBase64String(result));

            // 解密
            cipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpac);
            result = cipher.doFinal(result);
            System.out.println("jdk pbe decrypt:" + new String(result));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
